﻿#region All usings
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using senSimulator.DrawableComponents.Vehicles;
using senSimulator.DrawableComponents.TrafficLights.Types;

#endregion


namespace senSimulator.DrawableComponents.TrafficLights
{
    /// <summary>
    /// A class to make a set of traffic lighs for a direction
    /// North/West/South/East
    /// </summary>
    class CrossRoadDirection 
    {
        // The list of traffic lanes and lights
        private Dictionary<char, CrossRoadDirection> _otherCrossRoadDirections;
        private Dictionary<char, char> _compassToDirection;
        private Dictionary<int, TrafficLight> _trafficLights;
        private TrafficLane[] _trafficLanes;

        // Important variables for drawing
        private int _nrOfTrafficLanes;
        private int _nrOfTrafficLights;
        private Texture2D[] _textures;
        private Vector2[] _textureCenters;

        // Precalculated pixel locations, names and the direction
        private int[] _lanePositions            = { 100, 217, 251, 285, 319, 353, 377, 391, 415, 449, 483, 517, 551, 668 };
        private string[] _trafficLightNames     = { "1", "bo", "o", "o", "o", "o", "1", "2", "3", "4", "5", "6", "7", "8", "2" };
        private Vector2 _bicycleRightPosition   = Vector2.Zero;
        private Vector2 _bicycleLeftStraightPosition = Vector2.Zero;
        private char _direction;

        // Drawing locations and angle for all traffic lanes and lights
        private int[] _xAxisTrafficLanes;
        private int[] _yAxisTrafficLanes;
        private int[] _xAxisTrafficLights;
        private int[] _yAxisTrafficLights;
        private int _angleInDegrees;

        // Usefull stuff for drawing
        private Game _game;
        private float _gameSpeed;

        // SPAWN SETTING
        private int _spawnDistance;
        private Vector2 _spawnPosition;
                
        
        /// <summary>
        /// Constructor to initialize a basic traffic light set
        /// </summary>
        /// <param name="screenWidth">The horizontal size of the screen (in pixels)</param>
        /// <param name="screenHeight">The vertical size of the screen (in pixels)</param>
        /// <param name="direction">Which direction the traffic lights should face</param>
        /// <param name="game">The main game (class)</param>
        public CrossRoadDirection(char direction, Texture2D[] textures, Vector2[] textureCenters, float gameSpeed, int spawnDistance, Game game)
        {
            // Store all information into the variables
            _trafficLanes       = new TrafficLane[_trafficLightNames.Length];
            _compassToDirection = new Dictionary<char, char>();
            _trafficLights      = new Dictionary<int,TrafficLight>();
            _nrOfTrafficLanes   = _lanePositions.Length;
            _textures           = textures;
            _textureCenters     = textureCenters;
            _direction          = direction;
            _gameSpeed          = gameSpeed;
            _spawnDistance      = spawnDistance;
            _game               = game;
            
            // Position the traffic lanes and lights
            TransformPixelLocations();
            PositionTrafficLanes();
            PositionTrafficLights();
        }


        /// <summary>
        /// The traffic needs to know the other directions they can go to. This setter gives
        /// all possible directions (n/w/s/e)
        /// </summary>
        /// <param name="allCrossRoadDirections">The dictionary of directions</param>
        public void SetOtherCrossRoadDirections(Dictionary<char, CrossRoadDirection> allCrossRoadDirections)
        {
            _otherCrossRoadDirections = allCrossRoadDirections;
        }


        /// <summary>
        /// Convert the axis to the correct pixel locations
        /// </summary>
        public void TransformPixelLocations()
        {
            // The settings to cross through
            int axisLength = _lanePositions.Length;
            _xAxisTrafficLanes = new int[axisLength];
            _yAxisTrafficLanes = new int[axisLength];
            _xAxisTrafficLights = new int[axisLength];
            _yAxisTrafficLights = new int[axisLength];

            int bicycleRightOffset = 12;
            switch (_direction)
            {
                case 'N':
                    // Set the angle and the X axis
                    _angleInDegrees = 180;
                    Array.Reverse(_lanePositions);          
                    _xAxisTrafficLanes = _lanePositions;
                    _xAxisTrafficLights = _lanePositions;

                    // Set the correct Y axis values
                    for (int i = 0; i < axisLength; i++)    // Set the value for the Y axis
                    {
                        _yAxisTrafficLanes[i] = 100;
                        _yAxisTrafficLights[i] = 190;
                    }

                    // Set the special location for the bicycle right (to prevent spawn issues)
                    _bicycleRightPosition = new Vector2(_xAxisTrafficLights[12]- bicycleRightOffset, _yAxisTrafficLights[12]);
                    _bicycleLeftStraightPosition = new Vector2(_xAxisTrafficLights[12] + bicycleRightOffset, _yAxisTrafficLights[12]);

                    // Add the conversion from compass direction to left, straignt and right (for busses and cars)
                    _compassToDirection.Add('W', 'R');
                    _compassToDirection.Add('S', 'S');
                    _compassToDirection.Add('E', 'L');
                    _compassToDirection.Add('N', 'L');

                    // Set the spawn distance
                    _spawnPosition = new Vector2(0, -_spawnDistance);
                    break;

                case 'W':
                    // Set the angle and value for the X axis
                    _angleInDegrees = 90;
                    for (int i = 0; i < axisLength; i++)    
                    {
                        _xAxisTrafficLanes[i] = 100;
                        _xAxisTrafficLights[i] = 190;
                    }

                    // Set the Y axis
                    _yAxisTrafficLanes = _lanePositions;
                    _yAxisTrafficLights = _lanePositions;

                    // Set the special location for the bicycle right (to prevent spawn issues)
                    _bicycleRightPosition = new Vector2(_xAxisTrafficLights[12], _yAxisTrafficLights[12] + bicycleRightOffset);
                    _bicycleLeftStraightPosition = new Vector2(_xAxisTrafficLights[12], _yAxisTrafficLights[12] - bicycleRightOffset);

                    // Add the conversion from compass direction to left, straignt and right (for busses and cars)
                    _compassToDirection.Add('S', 'R');
                    _compassToDirection.Add('E', 'S');
                    _compassToDirection.Add('N', 'L');
                    _compassToDirection.Add('W', 'L');

                    // Set the spawn distance
                    _spawnPosition = new Vector2(-_spawnDistance, 0);
                    break;

                case 'S':
                    // Set the angle and value for the X axis
                    _angleInDegrees = 0;
                    _xAxisTrafficLanes = _lanePositions;
                    _xAxisTrafficLights = _lanePositions;

                    // Set the value for the Y axis
                    for (int i = 0; i < axisLength; i++)    
                    {
                        _yAxisTrafficLanes[i] = 668;
                        _yAxisTrafficLights[i] = 578;
                    }

                    // Set the special location for the bicycle right (to prevent spawn issues)
                    _bicycleRightPosition = new Vector2(_xAxisTrafficLights[12] + bicycleRightOffset, _yAxisTrafficLights[12]);
                    _bicycleLeftStraightPosition = new Vector2(_xAxisTrafficLights[12] - bicycleRightOffset, _yAxisTrafficLights[12]);

                    // Add the conversion from compass direction to left, straignt and right (for busses and cars)
                    _compassToDirection.Add('E', 'R');
                    _compassToDirection.Add('N', 'S');
                    _compassToDirection.Add('W', 'L');
                    _compassToDirection.Add('S', 'L');

                    // Set the spawn distance
                    _spawnPosition = new Vector2(0, _spawnDistance);
                    break;

                case 'E':
                    // Set the angle and value for the X axis
                    _angleInDegrees = 270;
                    for (int i = 0; i < axisLength; i++) 
                    {
                        _xAxisTrafficLanes[i] = 668;
                        _xAxisTrafficLights[i] = 578;
                    }

                    // Use the reversed lane positions on th Y axis
                    Array.Reverse(_lanePositions);
                    _yAxisTrafficLanes = _lanePositions;
                    _yAxisTrafficLights = _lanePositions;

                    // Set the special location for the bicycle right (to prevent spawn issues)
                    _bicycleRightPosition = new Vector2(_xAxisTrafficLights[12], _yAxisTrafficLights[12] - bicycleRightOffset);
                    _bicycleLeftStraightPosition = new Vector2(_xAxisTrafficLights[12], _yAxisTrafficLights[12] + bicycleRightOffset);

                    // Add the conversion from compass direction to left, straignt and right (for busses and cars)
                    _compassToDirection.Add('N', 'R');
                    _compassToDirection.Add('W', 'S');
                    _compassToDirection.Add('S', 'L');
                    _compassToDirection.Add('E', 'L');

                    // Set the spawn distance
                    _spawnPosition = new Vector2(_spawnDistance, 0);
                    break;
            }
        }


        /// <summary>
        /// Create all traffic lanes
        /// </summary>
        public void PositionTrafficLanes()
        {
            // Pedestrian road: LEFT
            _trafficLanes[0] = new TrafficLane(_game, new Texture2D[] { _textures[0] }, new Vector2[] { _textureCenters[0] }, _xAxisTrafficLanes[0], _yAxisTrafficLanes[0], _angleInDegrees);
            // Exit lanes
            _trafficLanes[1] = new TrafficLane(_game, new Texture2D[] { _textures[1] }, new Vector2[] { _textureCenters[1] }, _xAxisTrafficLanes[1], _yAxisTrafficLanes[1], _angleInDegrees);
            _trafficLanes[2] = new TrafficLane(_game, new Texture2D[] { _textures[2] }, new Vector2[] { _textureCenters[2] }, _xAxisTrafficLanes[2], _yAxisTrafficLanes[2], _angleInDegrees);
            _trafficLanes[3] = new TrafficLane(_game, new Texture2D[] { _textures[2] }, new Vector2[] { _textureCenters[2] }, _xAxisTrafficLanes[3], _yAxisTrafficLanes[3], _angleInDegrees);
            _trafficLanes[4] = new TrafficLane(_game, new Texture2D[] { _textures[2] }, new Vector2[] { _textureCenters[2] }, _xAxisTrafficLanes[4], _yAxisTrafficLanes[4], _angleInDegrees);
            _trafficLanes[5] = new TrafficLane(_game, new Texture2D[] { _textures[2] }, new Vector2[] { _textureCenters[2] }, _xAxisTrafficLanes[5], _yAxisTrafficLanes[5], _angleInDegrees);
            // Pedestrian road: LEFT/MIDDLE + RIGHT/MIDDLE
            _trafficLanes[6] = new TrafficLane(_game, new Texture2D[] { _textures[3] }, new Vector2[] { _textureCenters[3] }, _xAxisTrafficLanes[6], _yAxisTrafficLanes[6], _angleInDegrees);
            _trafficLanes[7] = new TrafficLane(_game, new Texture2D[] { _textures[3] }, new Vector2[] { _textureCenters[3] }, _xAxisTrafficLanes[7], _yAxisTrafficLanes[7], _angleInDegrees);
            // Car lanes
            _trafficLanes[8] = new TrafficLane(_game, new Texture2D[] { _textures[4] }, new Vector2[] { _textureCenters[4] }, _xAxisTrafficLanes[8], _yAxisTrafficLanes[8], _angleInDegrees);
            _trafficLanes[9] = new TrafficLane(_game, new Texture2D[] { _textures[5] }, new Vector2[] { _textureCenters[5] }, _xAxisTrafficLanes[9], _yAxisTrafficLanes[9], _angleInDegrees);
            _trafficLanes[10] = new TrafficLane(_game, new Texture2D[] { _textures[6] }, new Vector2[] { _textureCenters[6] }, _xAxisTrafficLanes[10], _yAxisTrafficLanes[10], _angleInDegrees);
            // Bus lane
            _trafficLanes[11] = new TrafficLane(_game, new Texture2D[] { _textures[7] }, new Vector2[] { _textureCenters[7] }, _xAxisTrafficLanes[11], _yAxisTrafficLanes[11], _angleInDegrees);
            // Bicycle lane
            _trafficLanes[12] = new TrafficLane(_game, new Texture2D[] { _textures[8] }, new Vector2[] { _textureCenters[8] }, _xAxisTrafficLanes[12], _yAxisTrafficLanes[12], _angleInDegrees);
            // Pedestrian road: RIGHT
            _trafficLanes[13] = new TrafficLane(_game, new Texture2D[] { _textures[9] }, new Vector2[] { _textureCenters[9] }, _xAxisTrafficLanes[13], _yAxisTrafficLanes[13], _angleInDegrees);
        }


        /// <summary>
        /// Position all traffic lights
        /// </summary>
        /// <param name="screenWidth"></param>
        private void PositionTrafficLights()
        {

            // Pedestrian road: LEFT
            _trafficLights.Add(1, new TrafficLightForPedestrians(_game, _spawnPosition,
                new Texture2D[] { _textures[10], _textures[16], _textures[17], _textures[32] },
                new Vector2[] { _textureCenters[10], _textureCenters[16], _textureCenters[17], _textureCenters[32] },
                _xAxisTrafficLights[0], _yAxisTrafficLights[0], _angleInDegrees, _direction + _trafficLightNames[0], 30, this));
           
            // Pedestrian road: lEFT/MIDDLE
            _trafficLights.Add(2, new TrafficLightForPedestrians(_game, _spawnPosition,
                new Texture2D[] { _textures[11], _textures[18], _textures[19], _textures[32] },
                new Vector2[] { _textureCenters[11], _textureCenters[18], _textureCenters[19], _textureCenters[32] },
                _xAxisTrafficLights[6], _yAxisTrafficLights[6], _angleInDegrees, _direction + _trafficLightNames[6], 30, this));

            // Pedestrian road: RIGHT/MIDDLE
            _trafficLights.Add(3, new TrafficLightForPedestrians(_game, _spawnPosition,
                new Texture2D[] { _textures[11], _textures[18], _textures[19], _textures[32] },
                new Vector2[] { _textureCenters[11], _textureCenters[18], _textureCenters[19], _textureCenters[32] },
                _xAxisTrafficLights[7], _yAxisTrafficLights[7], _angleInDegrees, SpriteEffects.FlipHorizontally, _direction + _trafficLightNames[7], 30, this));

            // Traffic lights for cars
            _trafficLights.Add(4, new TrafficLightForCars(_game, _spawnPosition,
                new Texture2D[] { _textures[12], _textures[22], _textures[21], _textures[20], _textures[32] },
                new Vector2[] { _textureCenters[12], _textureCenters[22], _textureCenters[21], _textureCenters[20], _textureCenters[32] },
                _xAxisTrafficLights[8], _yAxisTrafficLights[8], _angleInDegrees, _direction + _trafficLightNames[8], 60));

            _trafficLights.Add(5, new TrafficLightForCars(_game, _spawnPosition,
                new Texture2D[] { _textures[12], _textures[22], _textures[21], _textures[20], _textures[32] },
                new Vector2[] { _textureCenters[12], _textureCenters[22], _textureCenters[21], _textureCenters[20], _textureCenters[32] },
                _xAxisTrafficLights[9], _yAxisTrafficLights[9], _angleInDegrees, _direction + _trafficLightNames[9], 60));

            _trafficLights.Add(6, new TrafficLightForCars(_game, _spawnPosition,
                new Texture2D[] { _textures[12], _textures[22], _textures[21], _textures[20], _textures[32] },
                new Vector2[] { _textureCenters[12], _textureCenters[22], _textureCenters[21], _textureCenters[20], _textureCenters[32] },
                _xAxisTrafficLights[10], _yAxisTrafficLights[10], _angleInDegrees, _direction + _trafficLightNames[10], 60));

            // Traffic light for bus
            _trafficLights.Add(7, new TrafficLightForBusses(_game, _spawnPosition,
                new Texture2D[] { _textures[13], _textures[23], _textures[24], _textures[25], _textures[26], _textures[27], _textures[32] },
                new Vector2[] { _textureCenters[13], _textureCenters[23], _textureCenters[24], _textureCenters[25], _textureCenters[26], _textureCenters[27], _textureCenters[32] },
                _xAxisTrafficLights[11], _yAxisTrafficLights[11], _angleInDegrees, _direction + _trafficLightNames[11], 65));

            // Traffic light for bicycle
            _trafficLights.Add(8, new TrafficLightForBicycles(_game, _spawnPosition,
                new Texture2D[] { _textures[14], _textures[29], _textures[28], _textures[32] },
                new Vector2[] { _textureCenters[14], _textureCenters[29], _textureCenters[28], _textureCenters[32] },
                _xAxisTrafficLights[12], _yAxisTrafficLights[12], _angleInDegrees, _direction + _trafficLightNames[12], 52));

            // Traffic Light for bicycle
            _trafficLights.Add(9, new TrafficLightForBicycles(_game, _spawnPosition,
                new Texture2D[] { _textures[15], _textures[31], _textures[30], _textures[32] },
                new Vector2[] { _textureCenters[15], _textureCenters[31], _textureCenters[30], _textureCenters[32] },
               (int)_bicycleRightPosition.X, (int)_bicycleRightPosition.Y, _angleInDegrees, _direction + _trafficLightNames[13], 52));

            // Pedestrian road: RIGHT
            _trafficLights.Add(10, new TrafficLightForPedestrians(_game, _spawnPosition,
                new Texture2D[] { _textures[10], _textures[16], _textures[17], _textures[32] },
                new Vector2[] { _textureCenters[10], _textureCenters[16], _textureCenters[17], _textureCenters[32] },
                _xAxisTrafficLights[13], _yAxisTrafficLights[13], _angleInDegrees, SpriteEffects.FlipHorizontally, _direction + _trafficLightNames[14], 30, this));

            // Find the number of traffic lanes (to draw)
            _nrOfTrafficLights = _trafficLights.Count();
        }


        /// <summary>
        /// Change the state of a traffic light based on the protocol, which needed to be converted
        /// </summary>
        /// <param name="trafficLightID"></param>
        public void SetTrafficLightState(int trafficLightNr, int state)
        {
            // Convert protocol to real world traffic light control
            switch (trafficLightNr)
            {
                // First check which traffic light is screwed :)
                case 1: // First pedestrian lane
                    _trafficLights[trafficLightNr].ChangeTrafficLightState(state);
                    _trafficLights[trafficLightNr + 1].ChangeTrafficLightState(state);
                    break;
                case 2: // Second pedestrian lane
                    _trafficLights[trafficLightNr + 1].ChangeTrafficLightState(state);
                    _trafficLights[trafficLightNr + 8].ChangeTrafficLightState(state);
                    break;
                case 3: // Car left (the same for all cars)
                case 4: // Car center
                case 5: // Car right
                case 6: // BUS
                case 7: // Bicycle
                case 8: // Bicycle
                    _trafficLights[trafficLightNr + 1].ChangeTrafficLightState(state);
                    break;       
            }
        }


        /// <summary>
        /// Add a traffic to the correct traffic light
        /// </summary>
        /// <param name="trafficLightID"></param>
        public string AddTraffic(string vehicleName, string from, string to)
        {
            Traffic traffic;
            Random randomGenerator = new Random();
            int randomTexture = 0;
            char direction = _compassToDirection[to.ElementAt(0)];
            switch (vehicleName)
            {
                case "CAR":
                    // Create a new car
                    randomTexture = randomGenerator.Next(33,36);
                    traffic = new Car(_game, _textures[randomTexture], _textureCenters[randomTexture], 0, 0, _angleInDegrees, _gameSpeed, from, to);

                    // Check which direction it will go
                    if (direction == 'L')
                    {
                        _trafficLights[4].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                        return _trafficLights[4].getName();
                    }
                    else if (direction == 'S')
                    {
                        _trafficLights[5].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                        return _trafficLights[5].getName();
                    }
                    else if (direction == 'R')
                    {
                        _trafficLights[6].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                        return _trafficLights[6].getName();
                    }
                    break;
                case "BUS":
                    traffic = new Bus(_game, _textures[36], _textureCenters[36], 0, 0, _angleInDegrees, _gameSpeed, from, to, direction);
                    _trafficLights[7].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                    return _trafficLights[7].getName();
                case "BICYCLE":
                    randomTexture = randomGenerator.Next(37, 39);
                    traffic = new Bicycle(_game, _textures[randomTexture], _textureCenters[randomTexture], 0, 0, _angleInDegrees, _gameSpeed, from, to);
                    if (direction.Equals('R'))
                    {
                        _trafficLights[9].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                        return _trafficLights[9].getName();
                    }
                    else
                    {
                        _trafficLights[8].AddTraffic(traffic, _otherCrossRoadDirections[to.ElementAt(0)]);
                        return _trafficLights[8].getName();
                    }
                case "PEDESTRIAN":
                    randomTexture = randomGenerator.Next(39, 42);
                    traffic = new Pedestrian(_game, _textures[randomTexture], _textureCenters[randomTexture], 0, 0, _angleInDegrees, _gameSpeed / 2, from, to);
                    
                    // Check which direction it will go
                    if (direction == 'L')
                    {
                        // If pedestrians go left, they will use the same cross road direction as arival, only inverse
                        this.AddPedestrianToTrafficLight(false, traffic);
                        return "";
                    }
                    else if (direction == 'S')
                    {
                        // First check which direction is the right cross road direction
                        _otherCrossRoadDirections[_compassToDirection.Keys.First()].AddPedestrianToTrafficLight(true, traffic);
                        return "";
                    }
                    else
                    {
                        Console.WriteLine("Pedestrians aren't stupid... You silly thing!");
                        return "";
                    }
            }
            return "";
        }


        /// <summary>
        /// Add a pedestrian to the traffic light, based on parameters:
        /// This function has been made because pedestrians need to walk over
        /// a different crossroad direction.
        /// </summary>
        /// <param name="forward">Tells if a pedestrian is walking from traffic light 1 to 8 or inverse</param>
        /// <param name="traffic">The pedestrian him/her -self</param>
        /// <returns></returns>
        public string AddPedestrianToTrafficLight(bool forward, Traffic traffic)
        {
            if (forward)
            {
                _trafficLights[1].AddPedestrian(traffic, this, new TrafficLight[] { _trafficLights[3], _trafficLights[10] }, false);
                return _trafficLights[1].getName();
            }
            else
            {
                _trafficLights[10].AddPedestrian(traffic, this, new TrafficLight[] { _trafficLights[2], _trafficLights[1] }, false);
                return _trafficLights[10].getName();
            }
        }


        /// <summary>
        /// Switch a pedestrian from traffic light
        /// </summary>
        /// <param name="pedestrian">The pedestrian</param>
        /// <param name="from">From traffic light</param>
        /// /// <param name="controller">Controller</param>
        public void SwitchPedestrianFromTrafficLight(Pedestrian pedestrian, TrafficLight fromTrafficLight, Controller controller)
        {
            // Add the pedestrian to the new traffic light, remove it from the old one and send the sensor values
            TrafficLight towardsTrafficLight = pedestrian.GetSecondTrafficLight();
            towardsTrafficLight.AddPedestrian(pedestrian, this, null, true);
            controller.SendSensorTriggerToController(towardsTrafficLight.getName(), 100, pedestrian.GetTo());
        }


        /// <summary>
        /// Get the nearest exit lane position (for car movement)
        /// </summary>
        /// <param name="currentPosition"></param>
        /// <returns></returns>
        public Vector2 GetNearestExitLane(float posX, float posY, string type)
        {
            // Initialize the basic parameters
            Vector2 _closestExit = Vector2.Zero;

            for (int index = 0; index < _trafficLightNames.Length; index++)
            {
                // If it is an exit lane (else skip it)
                if ((_trafficLightNames[index] == "o" && !type.Equals("bicycle")) || (type.Equals("bicycle") && _trafficLightNames[index] == "bo"))
                {
                    // If it has no value yet, set the first coördinate in it
                    if (_closestExit == Vector2.Zero)
                    {
                        _closestExit = new Vector2(
                            _xAxisTrafficLanes[index],
                            _yAxisTrafficLanes[index]
                            );
                    }// Else check if the lane is closer to the car
                    else
                    {
                        // Get the distance
                        float curXDist = posX - _closestExit.X;
                        float curYDist = posY - _closestExit.Y;
                        float newXDist = posX - _xAxisTrafficLanes[index];
                        float newYDist = posY - _yAxisTrafficLanes[index];

                        // Invert if needed
                        if (curXDist < 0)
                            curXDist *= -1;

                        if (curYDist < 0)
                            curYDist *= -1;

                        if (newXDist < 0)
                            newXDist *= -1;

                        if (newYDist < 0)
                            newYDist *= -1;

                        // If the distance is smaller, then it's a winner!
                        if (newXDist + newYDist < curXDist + curYDist)
                        {
                            _closestExit.X = _xAxisTrafficLanes[index];
                            _closestExit.Y = _yAxisTrafficLanes[index];
                        }
                    }
                }
            }

            return _closestExit;
        }


        /// <summary>
        /// Get the spawn vector
        /// </summary>
        public Vector2 GetSpawnVector()
        {
            return _spawnPosition;
        }


        /// <summary>
        /// Move the traffic
        /// </summary>
        public void MoveTraffic()
        {
            for (int i = 0; i < _nrOfTrafficLights; i++)
            {
                _trafficLights[i + 1].MoveTraffic((Controller)_game);
            }
        }


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void DrawTrafficLanes(GameTime gameTime, SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _nrOfTrafficLanes; i++)
            {
                _trafficLanes[i].Draw(gameTime, spriteBatch);
            }
        }


        /// <summary>
        /// Draw traffic
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void DrawTraffic(GameTime gameTime, SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _nrOfTrafficLights; i++)
            {
                _trafficLights[i + 1].DrawTraffic(gameTime, spriteBatch);
            }
        }


        /// <summary>
        /// Draw the traffic lights
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void DrawTrafficLights(GameTime gameTime, SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _nrOfTrafficLights; i++)
            {
                _trafficLights[i + 1].DrawTrafficLight(gameTime, spriteBatch);
            }
        }
    }
}
